#!/usr/bin/env python

# General imports
import inspect
import sys
import time
import datetime
import random

# Required for one-way encryption
import base64
import sha

# Required for two-way decryption
import httplib, urlparse, urllib

# Iservices-specific imports
from issohelpers import IssoHelpers
from dataobject import *

# Iservices-specific Exception classes
from exception import IservicesException
from exception import IservicesSysException

# Error codes and constants
from errcode import *
from constants import *
from properties import Properties

# Required for logging
import logging
from logutil import LogUtil

class IssoService(object):
    """
    This class holds the business logic of the SSO application.
    """

    def __init__(self):
        LogUtil.log(logging.INFO, 'IssoService.init(): Entry')
    
    def generateCookie(sGinu):
        """
        This function generates unique session cookies.
        """
        # Check if required data is provided
        if sGinu == None or sGinu == "":
            LogUtil.log(logging.ERROR,
                        'generateCookie(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Get a random float, convert to string
        ID = str(random.random())
        md = sha.new(ID)        
        shaBytes = md.digest()
        shaBytes = shaBytes + str(59)
        sUniqueID = base64.encodestring(shaBytes)
        sUniqueID = sUniqueID[0:len(sUniqueID)-1]
        LogUtil.log(logging.DEBUG,
                    'generateCookie(): Created Cookie=' + str(sUniqueID))
        
        # Save Session Cookie in DB
        sCookieForDB = IssoService._getOneWayEncValue(sUniqueID)
        LogUtil.log(logging.DEBUG,
                    'generateCookie(): Encrypted Cookie=' + str(sCookieForDB))
        LogUtil.log(logging.WARN,
                    'generateCookie(): Calling IssoHelpers.createCookie()')
        IssoHelpers.createCookie(sCookieForDB, sGinu, COOKIE_TYPE_SESSION)
        
        # Return Cookie
        LogUtil.log(logging.DEBUG,
                    'generateCookie(): Returning Cookie=' + str(sUniqueID))
        return sUniqueID

    def getIBrokerData(sIBrokerName):
        """
        This function returns data for the current IBroker.
        """
        if sIBrokerName == None or sIBrokerName == "":
            LogUtil.log(logging.ERROR,
                        'getIBrokerData(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Get IBroker object
        oIBroker = IssoHelpers.fetchIBroker(sIBrokerName)
        
        # Check if an IBroker object is returned or not
        if oIBroker == None:
            LogUtil.log(logging.ERROR,
                        'getIBrokerData(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[IBROKER_INVALID]))
            # Throw exception: Ibroker is not valid
            raise IservicesSysException(IBROKER_INVALID,
                                        dUtilErrorCodeMap[IBROKER_INVALID])
        
        return oIBroker
    
    def getPrincipalMetadata(sGinu):
        """
        This function returns the principal metadata including the personalized
        greeting.
        """
        # Check if global i-number is null
        if sGinu == None or sGinu == "":
            LogUtil.log(logging.ERROR,
                        'getPrincipalMetadata(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Get Principal metadata (personalized greeting)
        sGreeting = ""
        LogUtil.log(logging.WARN,
                    'getPrincipalMetadata(): Calling ' +
                    'IssoHelpers.getPersonalizedGreeting()')
        sEncGreeting = IssoHelpers.getPersonalizedGreeting(sGinu)
        if sEncGreeting == None:
            LogUtil.log(logging.ERROR,
                        'getPrincipalMetadata(): ' +
                        'IservicesSysException=IBroker is invalid')
            # Throw exception: Ibroker is not valid
            raise IservicesSysException(IBROKER_INVALID,
                                        dUtilErrorCodeMap[IBROKER_INVALID])
        else:
            sGreeting = IssoService._getTwoWayDecValue(sEncGreeting, sGinu)
        
        LogUtil.log(logging.DEBUG,
                    'getPrincipalMetadata(): Returning greeting=' + sGreeting)
        return sGreeting

    def login(sGinu, sIBrokerName, sSessionCookie, sMachineCookie,
              sPassword=None, bRememberMachine=None):
        """
        This function checks whether the user with sGinu as his global i-number
        is already signed in or not.
        """
        # Check if any required field is not provided
        if sGinu == None or sGinu == "":
            LogUtil.log(logging.ERROR, 'login(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        if  sIBrokerName == None or sIBrokerName == "":
            LogUtil.log(logging.ERROR, 'login(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Verify if principal belongs to same IBroker
        LogUtil.log(logging.WARN, 'login(): Calling verifyPrincipal()')
        bPrincipalVerified = IssoService.verifyPrincipal(sGinu, sIBrokerName)
        if not bPrincipalVerified:
            # Exception: User does not belong to this IBroker
            LogUtil.log(logging.DEBUG,
                        'login(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[IBROKER_PRINCIPAL_MISMATCH]))
            sReturn = dUtilErrorCodeMap[IBROKER_PRINCIPAL_MISMATCH]
            LogUtil.log(logging.INFO, 'login(): Returning Result=' + sReturn)
            return sReturn
        else:
            LogUtil.log(logging.INFO, 'login(): Verified Principal')
        
        # Verify Principal State
        bIsPrincipalActive = IssoService._isPrincipalStateActive(sGinu)
        if not bIsPrincipalActive:
            # Exception: Account is inactive
            LogUtil.log(logging.ERROR, 'login(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[ACCOUNT_INACTIVE]))
            sReturn = dUtilErrorCodeMap[ACCOUNT_INACTIVE]
            LogUtil.log(logging.INFO, 'login(): Returning Result=' + sReturn)
            return sReturn
        else:
            LogUtil.log(logging.INFO, 'login(): Principal is active')
        
        # Verify password/session
        if sPassword == None:
            LogUtil.log(logging.INFO, 'login(): Password=None')
            # Verify Session state
            bIsSessionActive = False
            try:
                LogUtil.log(logging.WARN, 'login(): Calling ' +
                            'verifySessionState() for ginu=' + str(sGinu) +
                            ' and session cookie=' + str(sSessionCookie))
                bIsSessionActive = IssoService.verifySessionState(
                    sGinu, sSessionCookie, True)
            except IservicesSysException:
                oEx = sys.exc_info()[1]
                LogUtil.log(logging.ERROR, 'login(): IservicesSysException=' +
                            str(dUtilErrorCodeMap[oEx.getCode()]))
                if oEx.getCode() == SESSION_PRINCIPAL_MISMATCH:                    
                    bIsSessionActive = False
                elif oEx.getCode() == ACCOUNT_INACTIVE:
                    raise
                elif oEx.getCode() == SESSION_INVALID:
                    bIsSessionActive = False
                else:
                    bIsSessionActive = False
            LogUtil.log(logging.DEBUG, 'login(): SessionActive=' +
                        str(bIsSessionActive))
            
            # Check if session is found to be active
            if bIsSessionActive:
                # Update Session Cookie Time in DB
                try:
                    # Fetch Cookie to get Cookie id
                    sSessionCookie = IssoService._getOneWayEncValue(
                        sSessionCookie)
                    LogUtil.log(logging.WARN, 'login(): Calling IssoHelpers.' +
                                'fetchCookie() for Session Cookie=' +
                                str(sSessionCookie))
                    oSessionCookie = IssoHelpers.fetchCookie(
                        sSessionCookie, COOKIE_TYPE_SESSION)
                    LogUtil.log(logging.INFO, 'login(): Got Session Cookie=' +
                                str(oSessionCookie))
                    if oSessionCookie != None:
                        LogUtil.log(logging.WARN, 'login(): Calling IssoHelpers'
                                    + '.updateCookie() for Cookie ID=' +
                                    str(oSessionCookie.getId()))
                        IssoHelpers.updateCookie(oSessionCookie.getId())
                        LogUtil.log(logging.DEBUG, 'login(): Updated Session')
                except Exception:
                    oEx = sys.exc_info()[1]
                    LogUtil.log(logging.INFO, 'login(): Exception=' + str(oEx))
                
                # Update Machine Cookie Time in DB
                try:
                    # Fetch Cookie to get Cookie id
                    sMachineCookie = IssoService._getOneWayEncValue(
                        sMachineCookie)
                    LogUtil.log(logging.WARN, 'login(): Calling IssoHelpers.' +
                                'fetchCookie() for Machine Cookie=' +
                                str(sMachineCookie))
                    oMachineCookie = IssoHelpers.fetchCookie(
                        sMachineCookie, COOKIE_TYPE_MACHINE)
                    LogUtil.log(logging.INFO, 'login(): Got Machine Cookie=' +
                                str(oMachineCookie))

                    if oMachineCookie != None:
                        LogUtil.log(logging.WARN, 'login(): Calling IssoHelpers'
                                    + '.updateCookie() for Cookie ID=' +
                                    str(oMachineCookie.getId()))
                        IssoHelpers.updateCookie(oMachineCookie.getId())
                        LogUtil.log(logging.DEBUG, 'login(): Updated Machine')
                except Exception:
                    oEx = sys.exc_info()[1]
                    LogUtil.log(logging.INFO, 'login(): Exception=' + str(oEx))

                # Login successful
                LogUtil.log(logging.INFO, 'login(): Returning Result=Success')
                return 'Success'
            else:
                # Verify machine cookie
                bIsMachineActive = False
                try:
                    LogUtil.log(logging.WARN, 'login(): Calling ' +
                                'verifySessionState() for ginu=' + str(sGinu) +
                                ' and Machine Cookie=' + str(sMachineCookie))
                    bIsMachineActive = IssoService.verifySessionState(
                        sGinu, sMachineCookie, False)
                except Exception:
                    oEx = sys.exc_info()[1]
                    LogUtil.log(logging.DEBUG, 'login(): Exception=' + str(oEx))
                    LogUtil.log(logging.DEBUG, 'login(): Setting Machine Cookie'
                                + ' Active=False')
                    bIsMachineActive = False
                
                # Check if machine cookie is found to be active
                if bIsMachineActive:
                    # Prompt for password
                    LogUtil.log(logging.INFO,
                                'login(): Returning Result=Password')
                    return "Password"
                else:
                    # Retry page
                    LogUtil.log(logging.INFO, 'login(): Returning Result=Retry')
                    return "Retry"

        else:
            LogUtil.log(logging.DEBUG, 'login(): Password <> None')
            if sPassword == '':
                LogUtil.log(logging.DEBUG, 'login(): Blank Password')
                LogUtil.log(logging.ERROR, 'login(): IservicesSysException=' +
                            str(dUtilErrorCodeMap[PWD_MISMATCH]))
                # Throw exception: Password does not match
                raise IservicesSysException(PWD_MISMATCH,
                                            dUtilErrorCodeMap[PWD_MISMATCH])
            
            # Encrypt password
            sEncryptedPassword = IssoService._getOneWayEncValue(sPassword)
            LogUtil.log(logging.DEBUG, 'login(): Encrypted Password=' +
                        sEncryptedPassword)
            
            # Get Principal Object
            oPrincipal = IssoHelpers.fetchPrincipal(sGinu)
            sActualPassword = oPrincipal.getPassword()
            if cmp(sEncryptedPassword, sActualPassword) == 0:
                try:
                    # Check if user chose to remember machine or not
                    LogUtil.log(logging.DEBUG, 'login(): RememberMachine=' +
                                str(bRememberMachine))
                    if bRememberMachine != None:
                        sMachineCookie = IssoService._getOneWayEncValue(
                            sMachineCookie)
                        LogUtil.log(logging.DEBUG, 'login(): Encrypted ' +
                                    'Machine Cookie=' + str(sMachineCookie))
                        if bRememberMachine:
                            # Update Machine Cookie Time in DB
                            LogUtil.log(logging.WARN, 'login(): Calling ' +
                                        'IssoHelpers.fetchCookie for Machine ' +
                                        'Cookie=' + str(sMachineCookie))
                            oMachineCookie = IssoHelpers.fetchCookie(
                                sMachineCookie, COOKIE_TYPE_MACHINE)
                            if oMachineCookie != None:
                                LogUtil.log(logging.WARN, 'login(): Calling ' +
                                            'IssoHelpers.updateCookie() for ' +
                                            'Machine Cookie ID=' +
                                            str(oMachineCookie.getId()))
                                IssoHelpers.updateCookie(oMachineCookie.getId())
                        else:
                            # Remove Machine Cookie from DB
                            LogUtil.log(logging.WARN, 'login(): Calling ' +
                                        'IssoHelpers.deleteCookie for Machine' +
                                        ' Cookie=' + str(sMachineCookie))
                            IssoHelpers.deleteCookie(
                                sMachineCookie, COOKIE_TYPE_MACHINE)
                except Exception:
                    oEx = sys.exc_info()[1]
                    LogUtil.log(logging.DEBUG, 'login(): While updating ' +
                                'machine cookie, Exception=' + str(oEx))
                LogUtil.log(logging.INFO, 'login(): Passwords matched, ' +
                            'Returning Result=Success')
                return "Success"
            else:
                LogUtil.log(logging.DEBUG, 'login(): Passwords not matched')
                LogUtil.log(logging.ERROR, 'login(): IservicesSysException=' +
                            str(dUtilErrorCodeMap[PWD_MISMATCH]))
                # Throw exception: Password does not match
                raise IservicesSysException(PWD_MISMATCH,
                                            dUtilErrorCodeMap[PWD_MISMATCH])
        
    def logout(sSessionCookie):
        """
        This function logs the user out of SSO application.
        """
        # Check if session cookie exists
        if sSessionCookie == None or sSessionCookie == '':
            LogUtil.log(logging.INFO, 'logout(): Session does not exist')
            LogUtil.log(logging.DEBUG, 'logout(): Returning Result=True')
            return True
        
        # Delete Session Cookie in DB
        LogUtil.log(logging.INFO, 'logout(): Session Cookie=' +
                    str(sSessionCookie))
        sEncCookie = IssoService._getOneWayEncValue(sSessionCookie)
        try:
            LogUtil.log(logging.WARN, 'logout(): Calling IssoHelpers.' +
                        'deleteCookie() for Session Cookie=' +
                        str(sEncCookie))
            IssoHelpers.deleteCookie(sEncCookie, COOKIE_TYPE_SESSION)
            LogUtil.log(logging.DEBUG, 'logout(): Deleted Session Cookie')
            LogUtil.log(logging.DEBUG, 'logout(): Returning Result=True')
            return True
        except Exception:
            oEx = sys.exc_info()[1]
            LogUtil.log(logging.DEBUG, 'logout(): While deleting session ' +
                        'cookie, Exception=' + str(oEx))
            LogUtil.log(logging.INFO, 'logout(): Session is already expired')
            LogUtil.log(logging.DEBUG, 'logout(): Returning Result=True')
            return True
    
    def verifyPrincipal(sGinu, sIBrokerName):
        """
        This function verifies if the principal is subscribed to the SSO service
        and for the said IBroker from which request has been received. It also
        checks the state if the principal is active or not.
        """
        # Check if required fields are provided
        if sGinu == None or sGinu == "":
            LogUtil.log(logging.ERROR,
                        'verifyPrincipal(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        if sIBrokerName == None or sIBrokerName == "":
            LogUtil.log(logging.ERROR,
                        'verifyPrincipal(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])

        try:    
            # Get IBroker object
            LogUtil.log(logging.DEBUG, 'verifyPrincipal(): Calling ' +
                        'IssoHelpers.fetchIBroker() for Broker=' + sIBrokerName)
            oIBroker = IssoHelpers.fetchIBroker(sIBrokerName)
            LogUtil.log(logging.DEBUG, 'verifyPrincipal(): Got Broker=' +
                        str(oIBroker))
            
            # Get Principal object
            LogUtil.log(logging.DEBUG, 'verifyPrincipal(): Calling ' +
                        'IssoHelpers.fetchPrincipal() for ginu=' + sGinu)
            oPrincipal = IssoHelpers.fetchPrincipal(sGinu)
            LogUtil.log(logging.DEBUG, 'verifyPrincipal(): Got Principal=' +
                        str(oPrincipal))
            
            # Check if an IBroker and Principal objects are returned or not
            if oIBroker == None or oPrincipal == None:
                # Exception: Ibroker is not valid
                LogUtil.log(logging.DEBUG,
                            'verifyPrincipal(): IservicesSysException=' +
                            str(dUtilErrorCodeMap[IBROKER_INVALID]))
                LogUtil.log(logging.DEBUG,
                            'verifyPrincipal(): Returning Result=False')
                return False
            
            # Compare ids
            if oIBroker.getId() == oPrincipal.getIBroker_id():
                LogUtil.log(logging.DEBUG,
                            'verifyPrincipal(): Returning Result=True')
                return True
            else:
                LogUtil.log(logging.DEBUG,
                            'verifyPrincipal(): Returning Result=False')
                return False
        except Exception:
            oEx = sys.exc_info()[1]
            LogUtil.log(logging.DEBUG,
                        'verifyPrincipal(): Exception=' + str(oEx))
            LogUtil.log(logging.DEBUG,
                        'verifyPrincipal(): Returning Result=False')
            return False
    
    def verifySessionState(sGinu, sCookie, bIsSessionCookie):
        """
        This function returns True if session state is active otherwise returns
        False
        """
        # Check if required fields are provided
        if sGinu == None or sGinu == "" or sCookie == None or sCookie == "":
            LogUtil.log(logging.ERROR,
                        'verifySessionState(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Encrypt cookie
        sCookie = IssoService._getOneWayEncValue(sCookie)
        LogUtil.log(logging.debug,
                    'verifySessionState(): Encrypted Cookie=' + sCookie)
        
        # Set cookie type
        if bIsSessionCookie:
            iCookieType = COOKIE_TYPE_SESSION
        else:
            iCookieType = COOKIE_TYPE_MACHINE
        
        try:
            # Get cookie object
            LogUtil.log(logging.WARN, 'verifySessionState(): Calling ' + 
                        'IssoHelpers.fetchCookie() for Cookie=' + sCookie +
                        ' and Type=' + str(iCookieType))
            oSessionCookie = IssoHelpers.fetchCookie(sCookie, iCookieType)
            LogUtil.log(logging.DEBUG, 'verifySessionState(): Got Cookie=' +
                        str(oSessionCookie))
            
            # Get principal object
            LogUtil.log(logging.WARN, 'verifySessionState(): Calling ' + 
                        'IssoHelpers.fetchPrincipal() for ginu=' + sGinu)
            oPrincipal = IssoHelpers.fetchPrincipal(sGinu)
            LogUtil.log(logging.DEBUG, 'verifySessionState(): Got Principal=' +
                        str(oPrincipal))
                
            # Check if the session cookie belongs to same principal
            if oSessionCookie != None and oPrincipal != None:
                if oPrincipal.getId() != oSessionCookie.getPrincipalId():
                    LogUtil.log(logging.ERROR,
                                'verifySessionState(): IservicesSysException='+
                                dUtilErrorCodeMap[SESSION_PRINCIPAL_MISMATCH])
                    # Throw exception: Session does not belong to principal
                    raise IservicesSysException(
                        SESSION_PRINCIPAL_MISMATCH,
                        dUtilErrorCodeMap[SESSION_PRINCIPAL_MISMATCH])
            
                # Verify principal state
                if oPrincipal.getState() != PRINCIPAL_STATE_ACTIVE:
                    LogUtil.log(logging.ERROR,
                                'verifySessionState(): IservicesSysException='+
                                dUtilErrorCodeMap[ACCOUNT_INACTIVE])
                    # Throw exception: Account is inactive
                    raise IservicesSysException(
                        ACCOUNT_INACTIVE, dUtilErrorCodeMap[ACCOUNT_INACTIVE])
                
                # Return cookie status
                sReturn = IssoService._isCookieActive(
                    oSessionCookie, iCookieType)
                LogUtil.log(logging.DEBUG, 'verifySessionState(): Returning ' +
                            'Result=' + str(sReturn))
                return sReturn
        except IservicesSysException:
            oEx = sys.exc_info()[1]
            LogUtil.log(logging.ERROR,
                        'verifySessionState(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[oEx.getCode()]))
            raise

    def _getOneWayEncValue(sStringToBeEncrypted):
        """
        This function returns the encrypted string.
        This function performs one-way encryption using SHA1 algorithm. Hash
        produced by the algorithm is stored as a fixed size String of 40
        characters. 
        """
        # Check if null string
        if sStringToBeEncrypted == None or sStringToBeEncrypted == "":
            LogUtil.log(logging.ERROR,
                        '_getOneWayEncValue(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Encrypt string
        md = sha.new(sStringToBeEncrypted)
        md = md.digest()
        sEncryptedData = base64.encodestring(md)
        sEncryptedData = sEncryptedData[0:len(sEncryptedData)-1]
        
        LogUtil.log(logging.DEBUG, '_getOneWayEncValue(): Returning Result=' +
                    sEncryptedData)
        return sEncryptedData
    
    def _getProperty(sKey):
        # Load resource bundle file
        sPath = inspect.getfile(sys._getframe(1))
        iLen = sPath.index ('/isso') + 5
        sPath = sPath[0:iLen]
        sPath = sPath + '/WEB-INF/classes/issoResources.properties'
        print sPath
        p = Properties()
        LogUtil.log(logging.WARN, '_getProperty(): Loading file=' + sPath)
        p.load(open(sPath))
        
        # Return Value for given Key
        LogUtil.log(logging.DEBUG, '_getProperty(): Returning Result=' +
                    p[sKey])
        return p[sKey]
    
    def _getTwoWayDecValue(sStringToBeDecrypted, sPassKey):
        """
        This function returns the decrypted string. sPassKey is global i-number
        of the Principal whose data is to be decrypted.
        This function calls a Java servlet that performs two-way decryption
        using PBEWithMD5AndTripleDES (Password Based Encryption with MD5 and
        Triple DES), which takes a SALT and a passkey to encrypt any string and
        produces a hash value. Size of the hash value varies with the length of
        the string to be encrypted.
        """
        # Check if required 
        if sStringToBeDecrypted == None or sStringToBeDecrypted == "":
            LogUtil.log(logging.ERROR,
                        '_getTwoWayDecValue(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        if sPassKey == None or sPassKey == "":
            LogUtil.log(logging.ERROR,
                        '_getTwoWayDecValue(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])
        
        # Gabe's Code
        pwd = sPassKey
        crypt = sStringToBeDecrypted
        service_url='http://localhost:8080/isso/Decrypt'
        (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(
            service_url)
        (host, port)=urllib.splitnport(netloc)
    
        if (crypt==""):
            qs="pwd="+urllib.quote(pwd)+"&clear="+urllib.quote(clear)
            #print "Asking for encryption using qs",qs
            
        else:
            qs="pwd="+urllib.quote(pwd)+"&crypt="+urllib.quote(crypt)
            #print "Asking for decryption using qs",qs
        httpobj = httplib.HTTPConnection(host, port)
        httpobj.putrequest('POST', path)
        httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
        httpobj.putheader('Content-length', '%d' % len(qs))
        httpobj.endheaders()
        httpobj.send(qs)
        resp= httpobj.getresponse()
        if resp.status!= 200:
            #raise exceptions.IOError()
            LogUtil.log(logging.FATAL,
                        '_getTwoWayDecValue(): For ginu=' + sPassKey + ' and ' +
                        'greeting=' + sStringToBeDecrypted + ', ' +
                        'Response Status Code=' + str(resp.status))
            sDecryptedString = ''
        else:
            sDecryptedString = resp.read()

        LogUtil.log(logging.DEBUG, '_getTwoWayDecValue(): Returning Result=' +
                    sDecryptedString)
        return sDecryptedString

    def _isCookieActive(oCookie, iCookieType):
        """
        This functions returns True if specified cookie is active, otherwise
        returns False.
        """
        LogUtil.log(logging.debug, '_isCookieActive(): Cookie=' + str(oCookie)+
                    ' and Cookie Type=' + str(iCookieType))
        # Check if required fields are provided
        if oCookie == None or oCookie == "":
            LogUtil.log(logging.ERROR,
                        '_isCookieActive(): IservicesSysException='
                        + str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])

        try:
            # Read expiry time from resources file and convert into milliseconds
            if iCookieType == COOKIE_TYPE_SESSION:
                lExpiryTime = int(IssoService._getProperty(
                    'session.server.validity.hours'))
                lExpiryTime = lExpiryTime * 60 * 60 * 1000
                LogUtil.log(logging.DEBUG, '_isCookieActive(): Session Cookie' +
                            ' ExpiryTime=' + str(lExpiryTime))
            else:
                lExpiryTime = int(IssoService._getProperty(
                    'machine.server.validity.days'))
                lExpiryTime = lExpiryTime * 24 * 60 * 60 * 1000
                LogUtil.log(logging.DEBUG, '_isCookieActive(): Machine Cookie' +
                            ' ExpiryTime=' + str(lExpiryTime))
            
            # Get Cookie modification time and convert it into milliseconds
            sCookieModificationTime = oCookie.getModificationTime()
            LogUtil.log(logging.DEBUG, '_isCookieActive(): Cookie Mod Time =' +
                        str(sCookieModificationTime))
	    #####Time Split
	    sCookieModificationTime=str(sCookieModificationTime).split(".")[0]
            sCookieModificationTime = time.strptime(sCookieModificationTime, DEFAULT_TIME_FORMAT)

	    #lCookieModificationTime = time.mktime(
            #    sCookieModificationTime.timetuple())
	    lCookieModificationTime = time.mktime(sCookieModificationTime)
            lCookieModificationTime *= 1000
            LogUtil.log(logging.DEBUG, '_isCookieActive(): Cookie Mod Time=' +
                        str(lCookieModificationTime))
            lCookieExpiryTime = lCookieModificationTime + lExpiryTime
            LogUtil.log(logging.DEBUG, '_isCookieActive(): Cookie Expiry Time='
                        + str(lCookieExpiryTime))

            # Get current time in milliseconds
            lCurrentTime = time.time() * 1000
            LogUtil.log(logging.DEBUG, '_isCookieActive(): Current Time='
                        + str(lCurrentTime))
            
            # Get Cookie state id
            iCookieStateID = oCookie.getState()
            iActiveStateID = COOKIE_STATE_ACTIVE
            
            # Check Cookie status
            bIsCookieActive = iCookieStateID == iActiveStateID
            bIsCookieNotExpired = lCookieExpiryTime > lCurrentTime
            if bIsCookieActive and bIsCookieNotExpired:
                LogUtil.log(logging.DEBUG,
                            '_isCookieActive(): Returning Result=True')
                return True
            else:
                LogUtil.log(logging.DEBUG,
                            '_isCookieActive(): Returning Result=False')
                return False
        except IservicesSysException:
            oEx = sys.exc_info()[1]
            LogUtil.log(logging.ERROR,
                        '_isCookieActive(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[oEx.getCode()]))
            raise

    def _isPrincipalStateActive(sGinu):
        """
        This functions returns True if principal with specified global i-number
        is active, otherwise returns False.
        """
        # Check if required fields are provided
        if sGinu == None or sGinu == "":
            LogUtil.log(logging.ERROR,
                        '_isPrincipalStateActive(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[INSUFFICENT_DATA]))
            # Throw exception: Insufficient Data
            raise IservicesSysException(INSUFFICENT_DATA,
                                        dUtilErrorCodeMap[INSUFFICENT_DATA])

        try:
            # Get Principal object
            LogUtil.log(logging.WARN, '_isPrincipalStateActive(): Calling ' +
                        'IssoHelpers.fetchPrincipal() for ginu=' + sGinu)
            oPrincipal = IssoHelpers.fetchPrincipal(sGinu)
            LogUtil.log(logging.DEBUG, '_isPrincipalStateActive(): Got ' +
                        'Principal=' + str(oPrincipal))
            
            # Check if a Principal object is returned or not
            if oPrincipal != None:
                iStateID = oPrincipal.getState()
                iActiveStateID = PRINCIPAL_STATE_ACTIVE
                if iStateID == iActiveStateID:
                    LogUtil.log(logging.DEBUG, '_isPrincipalStateActive(): ' +
                                'Returning Result=True')
                    return True
                else:
                    LogUtil.log(logging.DEBUG, '_isPrincipalStateActive(): ' +
                                'Returning Result=False')
                    return False
            else:
                LogUtil.log(logging.DEBUG, '_isPrincipalStateActive(): ' +
                            'Returning Result=False')
                return False
        except IservicesSysException:
            oEx = sys.exc_info()[1]
            LogUtil.log(logging.DEBUG,
                        '_isPrincipalStateActive(): IservicesSysException=' +
                        str(dUtilErrorCodeMap[oEx.getCode()]))
            LogUtil.log(logging.DEBUG, '_isPrincipalStateActive(): ' +
                        'Returning Result=False')
            return False
    
    generateCookie = staticmethod(generateCookie)
    getIBrokerData = staticmethod(getIBrokerData)
    getPrincipalMetadata = staticmethod(getPrincipalMetadata)
    login = staticmethod(login)
    logout = staticmethod(logout)
    verifyPrincipal = staticmethod(verifyPrincipal)
    verifySessionState = staticmethod(verifySessionState)
    _getOneWayEncValue = staticmethod(_getOneWayEncValue)
    _getProperty = staticmethod(_getProperty)
    _getTwoWayDecValue = staticmethod(_getTwoWayDecValue)
    _isCookieActive = staticmethod(_isCookieActive)
    _isPrincipalStateActive = staticmethod(_isPrincipalStateActive)
